<template>
  <div class="table-module">
    <!-- 查询 -->
    <!--
        配置查询条件
            首先去创建form表单，根据我们配置的查询条件去做一个循环判断，展示出不用类型所对应不同的输入框
            比如：text对应普通的输入框，select对应下拉选择，dateTime对应日期时间选择器
            在使用时，父组件会传来一个queryForm空的对象，
            循环出来的输入框会绑定表格配置中的prop字段绑定在queryForm对象中
     -->
    <div class="query" ref="queryRef">
      <div class="query-content">
        <el-form :model="props.tableModule.queryForm" style="display: flex;" label-position="left"
                 class="query-form">
          <el-form-item :label="item.label" style="margin-right: 20px; margin-bottom: 0px;"
                        v-for="item in props.tableModule.query" :key="item.prop">
            <el-input v-model="props.tableModule.queryForm[item.prop]" :placeholder="'输入' + item.label + '关键字'"
                      clearable v-if="item.type === 'text'"></el-input>
            <el-select v-model="props.tableModule.queryForm[item.prop]" clearable
                       :placeholder="'选择' + item.label + '关键字'" v-else-if="item.type === 'select'">
              <el-option v-for="cItem in item.options" :key="cItem[item.valueKey]"
                         :label="cItem[item.labelKey]" :value="cItem[item.valueKey]" />
            </el-select>
            <el-date-picker v-model="props.tableModule.queryForm[item.prop]" clearable type="datetimerange"
                            format="YYYY/MM/DD hh:mm:ss" value-format="x" range-separator="至" start-placeholder="开始时间"
                            end-placeholder="结束时间" v-else-if="item.type === 'date'" />
          </el-form-item>
        </el-form>
      </div>
      <div class="slot">
        <el-button @click="Search" type="primary" plain>查询</el-button>
        <el-button @click="Recover">重置</el-button>
        <!-- slot插槽（用来添加表格其他操作，比如，新增数据，删除数据等其他操作） -->
        <slot name="event"></slot>
        <!--
            动态表头显示，根据表格每条配置项中的show字段来决定改列是否显示或者隐藏
            columns 就是我们表格配置的数组对象
        -->
        <el-popover placement="bottom" title="表格配置" :width="200" trigger="click">
          <div v-for="(item, index) in props.tableModule.columns" :key="index">
            <el-checkbox v-model="item.show" :label="item.label" :true-label="1" :false-label="0" />
          </div>
          <template #reference>
            <el-button icon="Operation"></el-button>
          </template>
        </el-popover>
      </div>
    </div>
    <!-- 表格 -->
    <!-- style中是计算表格的高度的 -->
    <el-table :data="props.tableModule.dataList" border height="100%"
              :style="{ 'height': `calc(100vh - ${queryHeight + 156}px)` }" v-loading="props.tableModule.loading"
              :row-class-name="tableRowClassName" :cell-class-name="tableCellClassName" @cell-dblclick="cellDblClick"
              id="el-table" ref="tableRef">
      <el-table-column type="selection" width="50" align="center" />
      <!-- columns表格配置数据 -->
      <template v-for="(item, index) in props.tableModule.columns">
        <!-- 循环 columns 紧接着判断每个字段的类型 -->
        <el-table-column :prop="item.prop" :label="item.label" :align="item.align || 'left'" :width="item.width" :show-overflow-tooltip="item.showWordLimit"
                         :min-width="item.min_width" :fixed="item.fixed" v-if="item.show">
          <template slot-scope="scope" #default="scope">
            <!-- switch时使用switch开关组件，并且绑定好我们配置的属性 -->
            <div v-if="item.type === 'switch'">
              <el-switch v-model="scope.row[item.prop]" :active-value="item.activeValue"
                         :inactive-value="item.inactiveValue" @change="props.tableModule.switchChange(scope.row)">
              </el-switch>
            </div>
            <!-- status 时 使用fieldChange方法匹配出值对应的名称并返回 -->
            <div v-else-if="item.type === 'status'">
              <el-tag>{{
                  fieldChange(scope.row[item.prop], item.option) }}</el-tag>
            </div>
            <!-- image 就是使用 el-image展示我们的图片咯 -->
            <div v-else-if="item.type === 'image'">
              <el-image style="width: 60px; height: 60px" :src="scope.row[item.prop]"
                        :preview-src-list="[scope.row[item.prop]]" :preview-teleported="true">
              </el-image>
            </div>
            <!-- formatDate 方法将时间戳格式化为年月日时分秒的格式 -->
            <div v-else-if="item.type === 'time'">{{ scope.row[item.prop] }}</div>
            <!-- 可编辑单元格 -->
            <div v-else-if="item.isEdit">
              <div v-if="item.edit.type==='input'">
                <el-input v-model="scope.row[item.prop]" :placeholder="item.edit.placeholder"
                          @blur="inputBlur(scope.row)" autofocus ref="inputRef" :minlength="item.edit.minlength" :maxlength="item.edit.maxlength"
                          v-if="(scope.row['Indexs'] === rowIndex && scope.column['Indexs'] === columnIndex)"/>
                <div v-else>{{ scope.row[item.prop] }}</div>
              </div>


              <div v-else-if="item.edit.type==='select'">
                <el-select v-model="scope.row[item.prop]" :placeholder="item.edit.placeholder"
                           @change="(e)=>changeSelect(e, scope.row)" filterable clearable autofocus ref="selectRef" v-if="(scope.row['Indexs'] === rowIndex && scope.column['Indexs'] === columnIndex)">
                  <el-option v-for="cItem in item.edit.options" :value="cItem[item.edit.valueKey]"
                             :label="cItem[item.edit.labelKey]"/>
                </el-select>
                <div v-else>{{ fieldTranslate(scope.row[item.prop], item.edit.options,item.edit.labelKey,item.edit.valueKey) }}</div>
              </div>

              <div v-else-if="item.edit.type==='select'">
                <el-select v-model="scope.row[item.prop]" :placeholder="item.edit.placeholder"
                           @change="(e)=>changeSelect(e, scope.row)" filterable clearable autofocus ref="selectRef" v-if="(scope.row['Indexs'] === rowIndex && scope.column['Indexs'] === columnIndex)">
                  <el-option v-for="cItem in item.edit.options" :value="cItem[item.edit.valueKey]"
                             :label="cItem[item.edit.labelKey]"/>
                </el-select>
                <div v-else>{{ fieldTranslate(scope.row[item.prop], item.edit.options,item.edit.labelKey,item.edit.valueKey) }}</div>
              </div>

              <div v-else>{{ scope.row[item.prop] }}</div>
            </div>
            <!-- 类型都不匹配时直接展示 -->
<!--            <div v-else>{{ scope.row[item.prop] }}</div>-->
          </template>
        </el-table-column>
      </template>
      <!-- 用于列表的插槽操作列 -->
      <slot name="tableColumn"></slot>
    </el-table>
    <!-- 分页 -->
    <!-- 父组件传三个参数，当前页，每页条数，总条数就可以了。 -->
    <div class="page">
      <el-pagination :current-page="props.tableModule.pages?.page" :page-size.sync="props.tableModule.pages?.limit"
                     :page-sizes="pageSizes" :layout="layout" :total="props.tableModule.pages?.total" @size-change="sizeChange"
                     @current-change="currentChange" />
    </div>
  </div>
</template>

<script setup>
import { defineProps, onMounted, reactive, toRefs, ref } from 'vue'

const props = defineProps({
  tableModule: Object, // 由父组件传递而来
  layout: { // 分页功能配置
    type: String,
    default: "total, sizes, prev, pager, next, jumper",
  },
  pageSizes: { // 分页：每页条数配置
    type: Array,
    default() {
      return [10, 20, 30, 50];
    },
  },
})

const state = reactive({
  rowIndex: 0, // 行索引 用于可编辑单元格
  columnIndex: 0, // 列索引 用于可编辑单元格
  queryHeight: 0,
})

const {
  rowIndex,
  columnIndex,
  queryHeight,
} = toRefs(state)

const queryRef = ref(null);

onMounted(() => {
  // 这里拿到query模块的高度，适配页面高度的
  setTimeout(() => {
    state.queryHeight = queryRef.value.clientHeight
  }, 100);

  // 为每个表格配置项添加show属性，默认1为显示状态
  if (props.tableModule.columns){
    props.tableModule.columns.forEach(item => {
      item.show = 1
    })
  }
})

function fieldChange(row, option) {

  if (option[row]) {
    return option[row]
  }
}

function fieldTranslate(row, option,lableKey,valueKey) {

  let newVar = option.find(it => it[valueKey] === row);

  return newVar?.[lableKey]
}

// 编辑单元格 ----------
// 为每一行返回固定的className
function tableRowClassName({ row, rowIndex }) {
  row.Indexs = rowIndex;
}

// 为所有单元格设置一个固定的 className
function tableCellClassName({ column, columnIndex }) {
  column.Indexs = columnIndex;
}

// el-table单元格双击事件
function cellDblClick(row, column, cell, event) {
  state.rowIndex = row.Indexs
  state.columnIndex = column.Indexs
}

// input失去焦点
function inputBlur(row) {
  state.rowIndex = 0
  state.columnIndex = 0
  props.tableModule.editInputBlur(row) // 父组件的方法，
}

// select选择
function changeSelect(e, row) {

  state.rowIndex = 0
  state.columnIndex = 0
  props.tableModule.editInputBlur(row) // 父组件的方法，
}

// 每页条数切换时触发
function sizeChange(item) {
  props.tableModule.pages.limit = item
  props.tableModule.callback() // 父组件绑定的回调
}

// 页数切换时触发
function currentChange(item) {
  props.tableModule.pages.page = item
  props.tableModule.callback()
}

// 点击查询按钮时触发
function Search() {
  props.tableModule.callback()
}

// 点击重制触发
function Recover() {
  props.tableModule.queryForm = {}
  props.tableModule.callback()
}
</script>

<style scoped lang="scss">
.table-module {
  .query {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    margin-bottom: 10px;

    .query-content {
      display: flex;
      align-items: flex-start;

      .query-form {
        .el-form-item {
          margin: 0px;
          margin-right: 20px;
        }

        .el-input {
          width: 200px;
        }

        ::v-deep(.el-select) {
          .el-input {
            width: 200px;
          }
        }
      }
    }

    .slot {
      display: flex;
      justify-content: flex-end;
      padding-right: 48px;
    }
  }

  .page {
    margin-top: 10px;
  }
}
</style>
